package com.bootx.predict;

import com.bootx.predict.pojo.PredictPlugin;
import com.bootx.predict.pojo.PredictionResult;
import com.bootx.predict.pojo.RedPacketBatch;
import com.bootx.predict.pojo.RedPacketRecord;
import com.bootx.predict.util.PredictUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author black
 * 周期模式预测 (Cycle Pattern Strategy)
 */
@Component("cyclePatternPredict")
public class CyclePatternPredict extends PredictPlugin {
    @Override
    public String getName() {
        return "cyclePatternPredict";
    }

    @Override
    public List<PredictionResult> predict(List<RedPacketBatch> list, Set<Integer> indexes) {
        List<RedPacketRecord> history = PredictUtils.parseData(list);
        // 所有批次按顺序排序
        List<Long> sortedBatches = list.stream()
                .map(RedPacketBatch::getBatchId)
                .sorted()
                .toList();
        // 最新批次
        long currentBatch = sortedBatches.get(sortedBatches.size() - 1);
        List<PredictionResult> results = new ArrayList<>();
        for (int idx : indexes) {
            // 历史数据
            List<RedPacketRecord> records = history.stream()
                    .filter(r -> r.getIndex() == idx)
                    .sorted(Comparator.comparingLong(RedPacketRecord::getRoundId))
                    .toList();

            int total = records.size();
            int oddCount = (int) records.stream().filter(r -> PredictUtils.isAmountOdd(r.getAmount())).count();
            double avgOpenTime = records.stream().mapToInt(RedPacketRecord::getOpenTime).average().orElse(0);

            if (oddCount < 2) {
                results.add(new PredictionResult(idx, total, oddCount, 0.5, Double.valueOf(avgOpenTime+"").intValue()));
                continue;
            }

            // 提取奇数出现的批次位置
            List<Long> oddRounds = records.stream()
                    .filter(r -> PredictUtils.isAmountOdd(r.getAmount()))
                    .map(RedPacketRecord::getRoundId)
                    .sorted()
                    .toList();

            // 计算间隔
            List<Long> intervals = new ArrayList<>();
            for (int i = 1; i < oddRounds.size(); i++) {
                intervals.add(oddRounds.get(i) - oddRounds.get(i - 1));
            }
            // 找出最常见的周期
            Map<Long, Long> freq = intervals.stream()
                    .collect(Collectors.groupingBy(x -> x, Collectors.counting()));

            Optional<Map.Entry<Long, Long>> dominant = freq.entrySet().stream()
                    .max(Map.Entry.comparingByValue());

            double probability = 0.5;
            if (dominant.isPresent() && dominant.get().getValue() >= 2) {
                long cycle = dominant.get().getKey();
                long phase = (currentBatch - oddRounds.getLast()) % cycle;
                if (phase == 0) {
                    probability = 0.9;
                } else {
                    probability = 0.5;
                }
            }

            results.add(new PredictionResult(idx, total, oddCount, probability, Double.valueOf(avgOpenTime+"").intValue()));
        }
        return results;
    }
}
